package io.renren.modules.lucky.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.netty.util.internal.StringUtil;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.Query;
import io.renren.modules.app.utils.RestTemplateFactory;
import io.renren.modules.app.utils.StringUtils;
import io.renren.modules.lucky.dao.AppWxUserDao;
import io.renren.modules.lucky.entity.AppWxUserEntity;
import io.renren.modules.lucky.entity.WeiXinOpenIdInfoEntiy;
import io.renren.modules.lucky.entity.WeiXinUserInfoEntiy;
import io.renren.modules.lucky.service.AppWxUserService;
import io.renren.modules.sys.dao.SysConfigDao;
import io.renren.modules.sys.entity.SysConfigEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.security.MessageDigest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service("appWxUserService")
public class AppWxUserServiceImpl extends ServiceImpl<AppWxUserDao, AppWxUserEntity> implements AppWxUserService {

    @Autowired(required = false)
    private SysConfigDao configDao;

    @Autowired(required = false)
    private AppWxUserDao appWxUserDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AppWxUserEntity> page = this.page(
                new Query<AppWxUserEntity>().getPage(params), new QueryWrapper<AppWxUserEntity>()
        );
        return new PageUtils(page);
    }

    /**
     * @MethodName: 获取页面WXconfig授权信息
     * @Description: TODO
     * @Param: [url, timestamp, nonce_str]
     * @Return: java.lang.String
     * @Author: 泉哥倍儿帅
     * @Date: 2019/11/1
     **/
    @Override
    public String getWxJsSign(String url, String timestamp, String nonce_str) {
        try {
            String jsticket = getWxJSAPI();
            System.err.println(jsticket);
            String str = "jsapi_ticket=" + jsticket + "&noncestr=" + nonce_str + "&timestamp=" + timestamp + "&url="
                    + url;
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(str.getBytes("UTF-8"));
//            System.out.println(crypt.toString());
//            System.out.println(StringUtil.toHexString(crypt.digest()));
            String signature = StringUtils.SHA1(str);
            System.out.println(signature + "_________________" + StringUtil.toHexString(crypt.digest()));
//                    byteToHex(crypt.digest());
            return signature;
        } catch (Exception e) {
            log.error("保存信息失败,错误原因:" + e.getMessage(), e);
            e.printStackTrace();
        }
        return "1234";
    }

    /**
     * @MethodName: 获取jsapi_ticket
     * @Description: TODO
     * @Param: []
     * @Return: java.lang.String
     * @Author: 泉哥倍儿帅
     * @Date: 2019/11/1
     **/
    @Override
    public String getWxJSAPI() throws IOException {
        SysConfigEntity sysConfig = configDao.queryByKey("wx_app_jsapi_ticket");
        //获取储存的jsapi_ticket
        if (sysConfig.getParamValue() != null || sysConfig.getParamValue() != "") {
            Date d = sysConfig.getUpdateTime();
            Date now = new Date();
            long t = now.getTime() - d.getTime();
            //查看是否在有效期内
            if (t / 1000 > 7000) {
                //过期重新获取AccessToken
                String accessToken = getWxAccessToken();
                String jspUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=#ACCESS_TOKEN#&type=jsapi";
                String url = jspUrl.replace("#ACCESS_TOKEN#", accessToken);
                synchronized (AppWxUserServiceImpl.class) {
                    sysConfig = configDao.queryByKey("wx_app_jsapi_ticket");
                    if (sysConfig.getParamValue() != null || sysConfig.getParamValue() != "") {
                        if ((System.currentTimeMillis() - sysConfig.getUpdateTime().getTime())
                                / 1000 > 7000) {
                            String content = RestTemplateFactory
                                    .getResponse(RestTemplateFactory.generateGet(url, new HashMap<String, String>()));
                            if (content != null) {
                                ObjectMapper mapper = new ObjectMapper();
                                HashMap<?, ?> map = mapper.readValue(content, HashMap.class);
                                String token = (String) map.get("ticket");
                                sysConfig.setParamValue(token);
                                sysConfig.setUpdateTime(now);
                                configDao.updateById(sysConfig);
                                return token;
                            }
                        }
                    }
                }
            } else {
                return sysConfig.getParamValue();
            }
        }
        //若为空直接服务器获取
//        if (sysConfig.getParamValue() == null || sysConfig.getParamValue() == "") {
//            String ticket = getWxJSAPIFromService();
//            sysConfig.setParamValue(ticket);
//            configDao.updateById(sysConfig);
//            return ticket;
//        } else {
//            //判断是否失效
//            Date d = sysConfig.getUpdateTime();
//            Date now = new Date();
//            long t = now.getTime() - d.getTime();
//            //查看是否在有效期内
//            if (t / 1000 > 7000) {
//                String ticket = getWxJSAPIFromService();
//                sysConfig.setParamValue(ticket);
//                configDao.updateById(sysConfig);
//                return ticket;
//            }
//        }
        return sysConfig.getParamValue();
    }

    /**
     * @MethodName: 获取AccessToken
     * @Description: TODO
     * @Param: []
     * @Return: java.lang.String
     * @Author: 泉哥倍儿帅，坑货，token过期了咋整 更坑没更新就覆盖 欠干了！
     * @Date: 2019/11/1
     **/
    @Override
    public String getWxAccessToken() throws IOException {
        SysConfigEntity test = configDao.queryByKey("phone");
        SysConfigEntity sysConfig = configDao.queryByKey("wx_app_access_token");
        if (sysConfig.getParamValue() != null || sysConfig.getParamValue() != "") {
            Date d = sysConfig.getUpdateTime();
            Date now = new Date();
            long t = now.getTime() - d.getTime();
            if (t / 1000 > 7000) {
                String getAccesstUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx0a76c766f1a7a3d8&secret=0ebac6595fdd1cf0f61082ee8490002b";
                synchronized (AppWxUserServiceImpl.class) {
                    sysConfig = configDao.queryByKey("wx_app_access_token");
                    if (sysConfig.getParamValue() != null || sysConfig.getParamValue() != "") {
                        if ((System.currentTimeMillis() - sysConfig.getUpdateTime().getTime())
                                / 1000 > 7000) {
//                            String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret=" + appSecret
//                                    + "&code=" + code + "&grant_type=authorization_code";
                            String content = RestTemplateFactory.getResponse(
                                    RestTemplateFactory.generateGet(getAccesstUrl, new HashMap<String, String>()));
                            if (content != null) {
                                ObjectMapper mapper = new ObjectMapper();
                                HashMap<?, ?> map = mapper.readValue(content, HashMap.class);
                                String token = (String) map.get("access_token");
                                sysConfig.setParamValue(token);
                                sysConfig.setUpdateTime(now);
                                configDao.updateById(sysConfig);
                                return token;
                            }
                        }
                    }
                }
            }
            return sysConfig.getParamValue();
        }
        //如果为空，直接从服务器获取
//        if (sysConfig.getParamValue() == null || sysConfig.getParamValue() == "") {
//            String token = getWxAccessTokenFromService();
//            sysConfig.setParamValue(token);
//            configDao.updateById(sysConfig);
//            return token;
//        } else {
//            //若已有值，判断是否失效
//            Date d = sysConfig.getUpdateTime();
//            Date now = new Date();
//            long t = now.getTime() - d.getTime();
//            if (t / 1000 > 7000) {
//                String token = getWxAccessTokenFromService();
//                sysConfig.setParamValue(token);
//                configDao.updateById(sysConfig);
//                return token;
//            }
//        }

        return sysConfig.getParamValue();
    }

    private String getWxJSAPIFromService() throws IOException {
        String accessToken = getWxAccessToken();
        if (accessToken == null)
            return "";
        String jspUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=#ACCESS_TOKEN#&type=jsapi";
        String url = jspUrl.replace("#ACCESS_TOKEN#", accessToken);
        String content = RestTemplateFactory
                .getResponse(RestTemplateFactory.generateGet(url, new HashMap<String, String>()));
        if (content != null) {
            ObjectMapper mapper = new ObjectMapper();
            HashMap<?, ?> map = mapper.readValue(content, HashMap.class);
            String ticket = (String) map.get("ticket");
            return ticket;
        }
        return "";
    }

    /**
     * 从服务器获取新的token
     *
     * @return
     * @throws IOException
     */
    private String getWxAccessTokenFromService() throws IOException {
        String getAccesstUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx0a76c766f1a7a3d8&secret=0ebac6595fdd1cf0f61082ee8490002b";
        String content = RestTemplateFactory.getResponse(
                RestTemplateFactory.generateGet(getAccesstUrl, new HashMap<String, String>()));
        if (content != null) {
            ObjectMapper mapper = new ObjectMapper();
            HashMap<?, ?> map = mapper.readValue(content, HashMap.class);
            String token = (String) map.get("access_token");
            return token;
        }
        return null;
    }


    /**
     * @MethodName: 根据微信code获取openId
     * @Description: TODO
     * @Param: [code, appId, appSecret, wxType]
     * @Return: io.renren.modules.lucky.entity.WeiXinOpenIdInfoEntiy
     * @Author: 泉哥倍儿帅
     * @Date: 2019/11/1
     **/
    @Override
    public WeiXinOpenIdInfoEntiy getOpenIdInfo(String code, String appId, String appSecret, Integer wxType) {
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret=" + appSecret
                + "&code=" + code + "&grant_type=authorization_code";
        String content = RestTemplateFactory
                .getResponse(RestTemplateFactory.generateGet(url, new HashMap<String, String>()));
        ObjectMapper mapper = new ObjectMapper();
        WeiXinOpenIdInfoEntiy openIdInfoEntiy = null;
        System.out.println(content);
        try {
            openIdInfoEntiy = mapper.readValue(content, WeiXinOpenIdInfoEntiy.class);
            log.debug(">>>>open info=" + openIdInfoEntiy.toString());
        } catch (Exception e) {
            log.error("保存信息失败,错误原因:" + e.getMessage(), e);
            e.printStackTrace();
        }
        return openIdInfoEntiy;
    }

    /**
     * @MethodName: 根据OpenId获取用户信息
     * @Description: TODO
     * @Param: [openId, accessToken]
     * @Return: io.renren.modules.lucky.entity.WeiXinUserInfoEntiy
     * @Author: 泉哥倍儿帅
     * @Date: 2019/11/1
     **/
    @Override
    public WeiXinUserInfoEntiy getWeixinUserInfo(String openId, String accessToken, String latitude, String longitude) {
        String url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid="
                + openId + "&lang=zh_CN";
        String content = RestTemplateFactory
                .getResponse(RestTemplateFactory.generateGet(url, new HashMap<String, String>()));
        ObjectMapper mapper = new ObjectMapper();
        WeiXinUserInfoEntiy userInfo = null;
        try {
            userInfo = mapper.readValue(content, WeiXinUserInfoEntiy.class);
            userInfo.setAccess_token(accessToken);
            AppWxUserEntity userEntity = appWxUserDao.queryByOpenId(userInfo.getOpenid());
            //测试阶段暂时先用这个方式 过两天优化一下
            if (userEntity == null) {
                userEntity = new AppWxUserEntity();
                //存储微信用户信息
                userEntity.setOpenId(userInfo.getOpenid());
                userEntity.setWxSex(userInfo.getSex());
                userEntity.setWxNickname(userInfo.getNickname());
                userEntity.setWxProvince(userInfo.getProvince());
                userEntity.setWxUserhead(userInfo.getHeadimgurl());
                userEntity.setUnionId(userInfo.getUnionid());
                userEntity.setWxCountry(userInfo.getCountry());
                userEntity.setWxCity(userInfo.getCity());
                userEntity.setWxLatitude(latitude);
                userEntity.setWxLongitude(longitude);
                appWxUserDao.insert(userEntity);
            } else {
                //更新微信用户信息
                userEntity.setOpenId(userInfo.getOpenid());
                userEntity.setWxSex(userInfo.getSex());
                userEntity.setWxNickname(userInfo.getNickname());
                userEntity.setWxProvince(userInfo.getProvince());
                userEntity.setWxUserhead(userInfo.getHeadimgurl());
                userEntity.setUnionId(userInfo.getUnionid());
                userEntity.setWxCountry(userInfo.getCountry());
                userEntity.setWxCity(userInfo.getCity());
                userEntity.setWxLatitude(latitude);
                userEntity.setWxLongitude(longitude);
                appWxUserDao.updateById(userEntity);
                userInfo.setPhone(userEntity.getWxPhone());
            }
        } catch (Exception e) {
            log.error("保存信息失败,错误原因:" + e.getMessage(), e);
            e.printStackTrace();
        }
        return userInfo;
    }

    @Override
    public Boolean IsBindWechat(String phoneNum) {
        int count = appWxUserDao.countByPhone(phoneNum);
        return count > 0 ? true : false;
    }

    @Override
    public Boolean bindWechatWithPhone(String phoneNum, String openId) {
        AppWxUserEntity entity = appWxUserDao.queryByOpenId(openId);
        if (entity != null) {
            entity.setWxPhone(phoneNum);
            int flag = appWxUserDao.updateById(entity);
            return flag > 0 ? true : false;
        }
        return false;
    }

}